package com.lianniu.web.pay.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

public class YjfUtil {

  private static final Logger logger = LoggerFactory.getLogger(YjfUtil.class);
  /**
   * 将request取出的map转换成可读map
   * 
   * @param request
   * @return
   */
  @SuppressWarnings("rawtypes")
  public static Map<String,String> getParameterMap(HttpServletRequest request) {
    // 从request里获取到包装过的map
    Map<String, String[]>  properties = request.getParameterMap();
    //
    Map<String,String> returnMap = new HashMap<String,String>();
    Iterator<Entry<String, String[]>> entries = properties.entrySet().iterator();
    Map.Entry entry;
    String name = "";
    String value = "";
    while (entries.hasNext()) {
      entry = (Map.Entry) entries.next();
      name = (String) entry.getKey();
      Object valueObj = entry.getValue();
      if (null == valueObj) {
        value = "";
      } else if (valueObj instanceof String[]) {
        String[] values = (String[]) valueObj;
        for (int i = 0; i < values.length; i++) {
          value = values[i] + ",";
        }
        value = value.substring(0, value.length() - 1);
      } else {
        value = valueObj.toString();
      }
      // returnMap.put(name, value);

      returnMap.put(name, URLDecoder.decode(value));
    }
    return returnMap;
  }


  /**
   * map转换签名字符串
   * 
   * @param data
   * @return
   */
  public static String signString(Map<String, String> data) {

    Map<String, String> treeMap = new TreeMap<String, String>(data);

    StringBuilder sb = new StringBuilder();

    for (Entry<String, String> entry : treeMap.entrySet()) {
      if (entry.getKey().equals("sign")) {
        continue;
      }
      sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
    }

    sb.deleteCharAt(sb.length() - 1);

    return sb.toString();
  }



  /**
   * md5/SHA-256签名方法
   * 
   * @param str
   * 
   * @param function (MD5/SHA-256)
   * 
   * @return
   */
  public static String encryption(String str, String key, String function) {

    try {
      str = str.concat(key);
      System.out.println("signStr:" + str);
      byte[] toDigest = str.getBytes("UTF-8");
      MessageDigest md = MessageDigest.getInstance("md5");
      md.update(toDigest);
      return new String(Hex.encodeHex(md.digest()));
    } catch (Exception e) {
      throw new RuntimeException("签名计算失败：", e);
    }
  }



  /***
   * 生成请求链接
   * 
   * @param data
   * @return
   */
  public static String forLink(String gatewayUrl, Map<String, String> data) {

    StringBuilder sb = new StringBuilder();

    sb.append(gatewayUrl + "?");
    for (Entry<String, String> entry : data.entrySet()) {
      try {
        sb.append(
            String.format("%s=%s&", entry.getKey(), URLEncoder.encode(entry.getValue(), "UTF-8")));
        // sb.append(String.format("%s=%s&",entry.getKey(),entry.getValue(),"UTF-8"));
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    // 删除最后一个&连接号
    sb.deleteCharAt(sb.length() - 1);
    return sb.toString();
  }



  /**
   * 发送post请求
   * 
   * @param url
   * @param data
   * @param encoding
   * @return
   */
  public static HttpResponse postHttps(String gatewayUrl, Map<String, String> data,
      String encoding) {
    HttpResponse response = null;
    CloseableHttpClient httpclient = null;
    try {
      SSLContext sslContext =
          SSLContexts.custom().useTLS().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] chain, String authType) {// 信任所有证书
              return true;
            }
          }).build();
      SSLConnectionSocketFactory sslsf =
          new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
      httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

      HttpPost post = new HttpPost(gatewayUrl);

      StringBuilder sb = new StringBuilder();
      if (data != null) {
        sb.append("\n url 请求参数：[");
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        for (Map.Entry<String, ?> entry : data.entrySet()) {
          if (entry.getValue() == null) {
            continue;
          } else {
            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
          }
          sb.append(entry.getKey()).append("=").append(entry.getValue()).append(",");
        }
        try {
          post.setEntity(new UrlEncodedFormEntity(nvps, encoding));
        } catch (Exception e) {
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append("]");
      }

      response = httpclient.execute(post);

    } catch (Exception e) {
      e.printStackTrace();
    }

    return response;
  }



  /**
   * 验签
   * 
   * @param data
   * @param key
   * @return
   */
  public static boolean checkSign(Map<String, String> data, String key) {

    String signType = data.get("signType");
    String sign = data.get("sign");
    logger.info("传入的签名为："+sign);
    String newSign = encryption(signString(data), key, signType);
    logger.info("加密后的签名为："+newSign);
    if (newSign.equals(sign)) {
      return true;

    } else {
      return false;
    }


  }



  /**
   * response转换Json字符串
   * 
   * @param response
   */
  public static String responesParseJsionStr(HttpResponse response) {

    String result = null;

    if (null != response) {

      try {

        BufferedReader br =
            new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
        StringBuffer sb = new StringBuffer();

        String str = br.readLine();
        while (str != null) {
          sb.append(str + (char) 13 + (char) 10);
          str = br.readLine();
        }
        System.out.println("签名字符串" + sb.toString());
        result = sb.toString();

      } catch (Exception e) {
        e.printStackTrace();
      }

    }
    return result;
  }


  /**
   * JSON字符串转换成map
   * 
   * @param jsonObjStr e.g. {'name':'get','int':1,'double',1.1,'null':null}
   * @return Map
   */
  public static Map<String, String> JsonStrParseMap(String jsonObjStr) {

    JSONObject jsonObject = JSONObject.parseObject(jsonObjStr);

    Map<String, String> map = new TreeMap<String, String>();

    if (jsonObjStr != null || !jsonObjStr.equals("")) {
      for (Entry<String, Object> m : jsonObject.entrySet()) {
        map.put(m.getKey(), m.getValue().toString());
        System.out.println(m.getKey() + "=" + m.getValue());
      }
    }

    return map;
  }


}
